import unittest

from google.appengine.ext import db
from google.appengine.ext import testbed

RESULTS_DISPLAYED = 10
ATHLETES_STORED = 10

DAILY_BUDGET = 10000

##@details Captures the required information about every Athlete
class Athlete(db.Model):
    id = db.IntegerProperty(required=True)
    name = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    modified = db.DateTimeProperty(auto_now_add=True)
    cpc = db.IntegerProperty(required=True)
    
    # Track the impressions and clicks
    impressions = db.ListProperty(int, "Impressions by position", RESULTS_DISPLAYED * [0])
    clicks = db.ListProperty(int, "Clicks by position", RESULTS_DISPLAYED * [0])
    amount_paid = db.IntegerProperty(default=0)
    
    # Expected clicks (used for the new auction)
    ec = db.FloatProperty(default=0.0)
    # Whether we gathered enough data to use CR calculation
    new = db.BooleanProperty(default=True)
    out_of_budget = db.BooleanProperty(default=False)

    def print_column_names(self):
        cols = []
        for (key, _) in self.__dict__.iteritems():
            if not key in db.Model().__dict__:
                if key:
                    col_name = str(key)[1:].replace("_", " ").upper()
                    cols.append(col_name)
                else:
                    cols.append("")
        return "</th><th>".join(cols)
    
    def print_row(self):
        cols = []
        for (key, value) in self.__dict__.iteritems():
            if not key in db.Model().__dict__:
                if value:
                    cols.append(str(value))
                else:
                    cols.append("")
        return "</td><td>".join(cols)

##@details Captures the required information about every Athlete
class Stats(db.Model):
    profit = db.IntegerProperty(default=0)
    searches = db.IntegerProperty(default=0)
    clicks = db.ListProperty(int, "Number of clicks per position",
                             [0] * (RESULTS_DISPLAYED+1))
    top_names = db.StringListProperty()
    costs = db.ListProperty(int, "Actual costs", [0] * RESULTS_DISPLAYED)
    popularity = db.ListProperty(float, "Popularity factor", [1.0] * (ATHLETES_STORED+1))
    popularity_set = db.BooleanProperty(default=False)
    min_cpc_times = db.IntegerProperty(default=0)
    max_cpc_times = db.IntegerProperty(default=0)

    def print_column_names(self):
        cols = []
        for (key, _) in self.__dict__.iteritems():
            if not key in db.Model().__dict__:
                if key:
                    col_name = str(key)[1:].replace("_", " ").upper()
                    cols.append(col_name)
                else:
                    cols.append("")
        return "</th><th>".join(cols)
    
    def print_row(self):
        cols = []
        for (key, value) in self.__dict__.iteritems():
            if not key in db.Model().__dict__:
                if value:
                    cols.append(str(value))
                else:
                    cols.append("")
        return "</td><td>".join(cols)

class Explanation(db.Model):
    title = db.StringProperty()
    comments = db.StringListProperty("How much we get paid and why")

class ProfilerTestCase(unittest.TestCase):
    def setUp(self):
        # First, create an instance of the Testbed class.
        self.testbed = testbed.Testbed()
        # Then activate the testbed, which prepares the service stubs for use.
        self.testbed.activate()
        # Next, declare which service stubs you want to use.
        self.testbed.init_datastore_v3_stub()
    
    def tearDown(self):
        self.testbed.deactivate()
        
    def testInsertEntity(self):
        Athlete().put()
        self.assertEqual(1, len(Athlete.all().fetch(2)))